package my.yuan.fkzcommon.util.serialize;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtostuffIOUtil;
import io.protostuff.Schema;
import io.protostuff.runtime.RuntimeSchema;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @author qy
 * @description Protostuff序列化类
 * @date 2021-09-30
 */
public class ProtostuffUtil {
    private static final ConcurrentHashMap<Class<?>, Schema<?>> map = new ConcurrentHashMap<>();

    private ProtostuffUtil() {
    }


    private static <T> Schema<T> getSchema(Class<T> clz) {
        @SuppressWarnings("unchecked")
        Schema<T> schema = (Schema<T>) map.computeIfAbsent(clz, t -> RuntimeSchema.getSchema(clz));
        return schema;
    }


    public static <T> byte[] serialize(T obj) {
        @SuppressWarnings("unchecked")
        Class<T> clz = (Class<T>) obj.getClass();
        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        Schema<T> schema = getSchema(clz);
        try {
            return ProtostuffIOUtil.toByteArray(obj, schema, buffer);
        } finally {
            buffer.clear();
        }
    }

    public static <T> T deserialize(byte[] bytes, Class<T> clz) {
        try {
            T instance = clz.newInstance();
            @SuppressWarnings("unchecked")
            Schema<T> schema = (Schema<T>) map.get(clz);
            ProtostuffIOUtil.mergeFrom(bytes, instance, schema);
            return instance;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
